//-------------------------------------------------------------------------
/**
   File:   Color.h

   Descr.: - todo -

   Author: Stefan Leihkauf
   Date:   02.03.2014
*/
//-------------------------------------------------------------------------
#ifndef _COLOR_H
#define _COLOR_H

#include "common/types/typedef.h"

namespace cb { namespace gfx {

class Color
{
    float _color[4];

    enum { iR = 0, iG = 1, iB = 2, iA = 3 };

public:
    /// construction
    Color();
    Color(const Color& other);
    Color(float r, float g, float b, float a = 1.0f);

    /// initialization
    void Set(float r, float g, float b, float a);

    //-------------------------------------------------------------------------
    // The user is responsible to provide clamped [0.0; 1.0] values to the
    // non const methods.
    //-------------------------------------------------------------------------

    /// clamp value
    static float Clamp(float f);

    /// access red component
    inline float& R() { return _color[iR]; }
    inline float R() const { return _color[iR]; }

    /// access greeen component
    inline float& G() { return _color[iG]; }
    inline float G() const { return _color[iG]; }

    /// access blue component
    inline float& B() { return _color[iB]; }
    inline float B() const { return _color[iB]; }

    /// access alpha component
    inline float& A() { return _color[iA]; }
    inline float A() const { return _color[iA]; }

    /// equality
    bool operator == (const Color& other) const;

    /// assignment
    Color& operator = (const Color& other);

    //-------------------------------------------------------------------------
    // Constant index access will return 0.0 if the index is out of bounds.
    // 
    // The non const 'direct' index access will throw an debug assertion instead
    // whereas under non debug conditions the value may exceed the acceptable value range
    // and cause somewhat funny color effects.
    //-------------------------------------------------------------------------
    /// indexed access
    float& operator [] (int index);
    float operator [] (int index) const;

    //-------------------------------------------------------------------------
    // Convert color to framebuffer accepted values.
    // The color values will be clamped to [0.0;1.0] before conversion.
    //-------------------------------------------------------------------------

    /// convert to 2 byte 565 color
    ushort toRGB565() const;

    /// convert to 4 byte color
    unsigned toRGBA8888() const;

    //-------------------------------------------------------------------------
    // Create a color from framebuffer provided values.
    //-------------------------------------------------------------------------

    /// create from 2 byte 565 color
    static Color fromRGB565(ushort color);

    /// create from 4 byte color
    static Color fromRGBA8888(unsigned color);
};

}} // cb::gfx
#endif //!defined _COLOR_H